/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */


#include "test_mctp_class.h"
#include <test_utilities/test_base.h>
#include <mctp/pcie_transport.h>
#include <thread>
#include <chrono>

namespace {

// Test fixture
class pcie_transport_test : public mc::test::TestWithEngine {
protected:
    static void SetUpTestSuite() {
        TestWithEngine::SetUpTestSuite();
        // 动态创建服务实例，避免全局静态初始化导致的析构顺序问题
        m_test_service = mc::make_shared<test_service>();
        m_test_service->init();
        m_test_service->start();
        m_transport = mc::make_shared<dev::transport_object>();
    }

    static void TearDownTestSuite() {
        // 先清理依赖服务的对象
        if (m_transport) {
            m_transport.reset();
        }
        // 等待足够长的时间，确保对象清理完成
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
        // 然后停止并清理服务
        if (m_test_service) {
            m_test_service->stop();
            m_test_service.reset();
        }
        TestWithEngine::TearDownTestSuite();
    }

    static mc::shared_ptr<test_service> m_test_service;
    static mc::shared_ptr<dev::transport_object> m_transport;
};

mc::shared_ptr<test_service> pcie_transport_test::m_test_service = nullptr;
mc::shared_ptr<dev::transport_object> pcie_transport_test::m_transport = nullptr;

TEST_F(pcie_transport_test, init_Success) {
    mc::dict object = {
        {"bmc.kepler.Systems.Mctp.PCIeTransport",
         mc::dict{{"ServiceName", "TestService"},
                  {"TargetEid", static_cast<uint8_t>(5)},
                  {"TargetPhyAddr", static_cast<uint16_t>(0x0101)},
                  {"MessageType", static_cast<uint8_t>(2)}}},
    };

    bool result = m_transport->init(object);
    EXPECT_TRUE(result);
}

TEST_F(pcie_transport_test, init_EmptyDict) {
    mc::dict object;
    EXPECT_NO_THROW(m_transport->init(object));
}

TEST_F(pcie_transport_test, init_PartialFields) {
    // 目标：验证 init 方法处理部分字段缺失的情况
    mc::dict object = {
        {"bmc.kepler.Systems.Mctp.PCIeTransport",
         mc::dict{{"ServiceName", "TestService"}}},
    };

    EXPECT_NO_THROW(m_transport->init(object));
}

TEST_F(pcie_transport_test, init_InvalidType) {
    // 目标：验证 init 方法处理无效类型的情况
    mc::dict object = {
        {"bmc.kepler.Systems.Mctp.PCIeTransport",
         mc::dict{{"ServiceName", 12345},  // 无效类型
                  {"TargetEid", static_cast<uint8_t>(5)},
                  {"TargetPhyAddr", static_cast<uint16_t>(0x0101)},
                  {"MessageType", static_cast<uint8_t>(2)}}},
    };

    EXPECT_NO_THROW(m_transport->init(object));
}

// ========== transport_interface 属性测试 ==========

TEST_F(pcie_transport_test, transport_interface_Property) {
    // 目标：验证 transport_interface 属性可以正常访问
    EXPECT_TRUE(true);  // 属性存在即可
}

TEST_F(pcie_transport_test, MultipleInstances) {
    // 目标：验证可以创建多个 transport_object 实例
    std::vector<mc::shared_ptr<dev::transport_object>> transports;

    for (int i = 0; i < 3; ++i) {
        auto transport = mc::make_shared<dev::transport_object>();
        transports.push_back(transport);
    }

    EXPECT_EQ(transports.size(), 3);
}

} // namespace

